

<template>
  <el-dialog
    v-model="isModel"
    title="裁剪图片"
    width="1000px"
    destroy-on-close
    center
    draggable
  >
    <div class="main">
      <div class="tip">
        <div class="tip-text">上传说明"vue-cropper": "^1.0.9"版本</div>
      </div>
      <el-row :gutter="20">
        <el-col span="14">
          <div class="mainbox">
            <vue-cropper
              ref="cropper"
              :img="option.img"
              :outputSize="option.outputSize"
              :outputType="option.outputType"
              :info="option.info"
              :canScale="option.canScale"
              :autoCrop="option.autoCrop"
              :autoCropWidth="option.autoCropWidth"
              :autoCropHeight="option.autoCropHeight"
              :fixed="option.fixed"
              :fixedNumber="option.fixedNumber"
              :full="option.full"
              :fixedBox="option.fixedBox"
              :canMove="option.canMove"
              :canMoveBox="option.canMoveBox"
              :original="option.original"
              :centerBox="option.centerBox"
              :height="option.height"
              :infoTrue="option.infoTrue"
              :maxImgSize="option.maxImgSize"
              :enlarge="option.enlarge"
              :mode="option.mode"
              @realTime="realTime"
             
            >
            </vue-cropper>
            <div class="main-btn">
              <el-button  size="sm" @click="rotateLeft"
                >↺ 向左旋转15°</el-button
              >
              <el-button  size="sm" @click="rotateRight"
                >↻ 向左旋转15°</el-button
              >
              <el-button  size="sm" @click="changeScale(1)"  >+ 放大</el-button >
              
              <el-button  size="sm" @click="changeScale(-1)" >- 缩小</el-button >
              <el-button type="danger" size="sm" @click="changeReset"  >重置</el-button >
             
            </div>
          </div>
        </el-col>
        <el-col span="10">
          <div class="preview-model">
            <div class="preview" style="width: 200px; height: 200px" v-if="previews.url">
         
              <el-image
                lazy
                style="width: 100px; height: 100px"
                :src="previews.url"
                :zoom-rate="1.2"
                :max-scale="7"
                :min-scale="0.2"
                :preview-src-list="srcList"
                :initial-index="4"
                @load="lookImg"
            />
            </div>
            <div class="upload-btn">
              <el-upload v-model="file"  :on-change="selectImg">
                  <el-button type="primary" size="sm">选择图片</el-button>
              </el-upload>
              <el-button type="success" style="margin-left: 10px;" size="sm" @click="uploadFile">确认上传</el-button>
            </div>
          </div>
        </el-col>
      </el-row>
    </div>
  </el-dialog>

</template>
<script setup>
import { ref, reactive ,watch,defineExpose} from "vue";
import { VueCropper } from "vue-cropper";

import "vue-cropper/dist/index.css";
const isModel = ref(false);
const name = ref();
const file = ref();
const previews = ref({});
const previewImg = ref();
const cropper = ref(null);
const emit = defineEmits([""]);

const option = reactive({
  img: "",
  name: "",
  outputSize: 1, //裁剪生成图片的质量(可选0.1 - 1)
  outputType: "png", //裁剪生成图片的格式（jpeg || png || webp）
  info: true, //图片大小信息
  canScale: true, //图片是否允许滚轮缩放
  autoCrop: true, //是否默认生成截图框
  autoCropWidth: 200, //默认生成截图框宽度
  autoCropHeight: 200, //默认生成截图框高度
  fixed: false, //是否开启截图框宽高固定比例
  fixedNumber: [1.53, 1], //截图框的宽高比例
  full: false, //false按原比例裁切图片，不失真
  fixedBox: false, //固定截图框大小，不允许改变
  canMove: true, //上传图片是否可以移动
  canMoveBox: true, //截图框能否拖动
  original: false, //上传图片按照原始比例渲染
  centerBox: true, //截图框是否被限制在图片里面
  height: false, //是否按照设备的dpr 输出等比例图片
  infoTrue: false, //true为展示真实输出图片宽高，false展示看到的截图框宽高
  maxImgSize: 3000, //限制图片最大宽度和高度
  enlarge: 1, //图片根据截图框输出比例倍数
  mode: "100% 100%", //图片默认渲染方式
});

//预览
const srcList = ref([])


//当再次打开时 清空图片
watch(isModel, (val) => {
  if (!val) {
    previews.value = {};
    option.img = ''
    srcList.value = []
  }
});

//实时预览
const realTime = (data) => {
  previews.value = data;
  option.autoCropWidth = data.img.width;
  option.autoCropHeight = data.img.height;
};




//图片缩放
const changeScale = (num) => {
  num = num || 1;
  cropper.value.changeScale(num);
};

// 向左旋转
const rotateLeft = () => {
 cropper.value.rotate = cropper.value.rotate - 15 / 90;
 //直接旋转90度
  cropper.value.rotateLeft()
};

//向右旋转
const rotateRight = () => {
  cropper.value.rotate = cropper.value.rotate + 15 / 90;
  //直接旋转90度
  // cropper.value.rotateRight()
};

// 重置
const changeReset = () => {
  cropper.value.refresh();
};

//图片预览图片
const lookImg = () => {
  cropper.value.getCropBlob((data) => {
    file.value = data;
    let img = window.URL.createObjectURL(data);
    srcList.value.push(img)
  });
};


//选择图片
const selectImg = (e) => {
  //这里需要注意 每个UI组件 返回的数据格式不一样   需要什么取什么
  srcList.value = [];
  option.img = URL.createObjectURL(e.raw);
  option.name = e.raw.name;
 
};

/**
 * @function 确认上传
 *
 * */
const uploadFile = () => {
  cropper.value.getCropBlob((data) => {
    if (data) {
      data.fileName = option.name;
    }
    emit("uploadImgSuccess", data);
  });
};

/**
 * @function 开启弹窗
 * */
const open = () => {
  isModel.value = true;
};

/**
 * @function 关闭
 * */
const close = () => {
  isModel.value = false;
};

defineExpose({
  open,
  close,
});
</script>
<style lang="scss" scoped>
.main {
  box-sizing: border-box;
  min-height: 450px;
  padding: 20px;

  .tip {
    display: flex;
    align-items: center;
    margin-bottom: 20px;

    .tip-text {
      color: red;
    }
  }

  .mainbox {
    width: 100%;
    height: 300px;
  }

  .preview-model {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;

    .preview {
      overflow: hidden;
    }

    .upload-btn {
      display: flex;
      width: 100%;
      justify-content: space-evenly;
      margin-top: 20px;
    }
  }

  .main-btn {
    display: flex;
    justify-content: center;
    margin-top: 20px;
  }
}

</style>
